package com.bootdo.clouddo.service.sms;

import com.alibaba.fastjson.JSON;
import com.bootdo.clouddo.service.sms.impl.SysSMSSenderService;
import com.bootdo.clouddo.redis.CommonRedisService;
import com.bootdo.clouddo.utils.StringUtils;
import com.bootdo.clouddo.utils.common.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 发送短信服务类
 * @author xuzh
 *
 */
@Service
public class SMSCommonService {

	@Autowired
	private CommonRedisService commonRedisService;


	@Autowired
	private SysSMSSenderService sMSSenderService;
	
	/**
	 * 验证码失效为5分钟
	 */
	private static Long verifyCodeExpiredTime = 300l;

	/**
	 * 验证码生成时间间隔为120s
	 */
	private Long genCodeTime = 120l;
	
	public static final	Logger logger=LoggerFactory.getLogger(SMSCommonService.class);

	/**
	 * 发送验证码，同时将验证码信息放入redis
	 * @param mobile
	 * @param type
	 * @param key
	 * @return
	 * @throws Exception 
	 */
	public void doSendVerifySMS(String mobile, String type, String key, String ipAddress, String smsType) throws Exception {
		//limitIpAddressSendSMS(ipAddress);
		String code = genVerifyCode();
		if (smsType == null) {
			smsType = "default";
		}
		doSendVerifyCodeByType(mobile, code, type, smsType);
		
		Map<String,String> map = new HashMap<String, String>();
		map.put("mobile", mobile);
		map.put("type", type);
		map.put("key", key);
		map.put("ipAddress", ipAddress);
		logger.warn("send message info {}", JSON.toJSONString(map));
		
		//将验证码放入redis
		putVerifyCodeToRedis(key, code);
	}
	
	private void doSendVerifyCodeByType(final String mobile,final String code, final String type, final String smsType) throws Exception {
		if(!CommonUtils.matchMobile(mobile)){
			throw new Exception("mobile_invalid");
		}
		long startTime = System.currentTimeMillis();
		logger.info("send message start............");
		sMSSenderService.doSendSMS(mobile, code, type);
		logger.info("send message end..........");
		logger.info("send time :"+(System.currentTimeMillis()-startTime)+"ms");
	}

	/**
	 * 生成四位验证码
	 * 
	 * @return
	 */
	private String genVerifyCode() {
		Random r = new Random();
		int from = 100000;
		int to = 999999;
		return String.valueOf(from + r.nextInt(to - from));
	}

	/**
	 * 放进Redis
	 * 
	 * @param key
	 *            : example SysSMSLog.TYPE_WITHDRAW + mobile
	 * @param code
	 */
	private void putVerifyCodeToRedis(String key, String code) {
		Map<String, Object> codeCache = new HashMap<String, Object>();
		codeCache.put("code", code);
		codeCache.put("time", new Timestamp(System.currentTimeMillis()));
		commonRedisService.put(key, codeCache, verifyCodeExpiredTime);
	}

	@SuppressWarnings({ "unchecked" })
	private Map<String, Object> getVerifyCodeFromRedis(String key) {
		Object obj = commonRedisService.get(key);
		if (obj == null) {
			return null;
		}
		return (Map<String, Object>) obj;
	}

	public void removeMobileVerifyCode(String key) {
		if (StringUtils.isNotEmpty(key)) {
			commonRedisService.remove(key);
		}
	}

	/**
	 * 判断传过来的code是否合法
	 * 
	 * @param code
	 * @param key
	 *            : example SysSMSLog.TYPE_WITHDRAW + mobile
	 * @return true 合法; false 非法
	 */
	public boolean ifVerifyCodeValid(String code, String key) {
		Map<String, Object> map = getVerifyCodeFromRedis(key);
		if (map == null) {
			return false;
		}
		String sysCode = (String) map.get("code");
		if (sysCode.equals(code))
			return true;
		else {
			return false;
		}
	}

	/**
	 * 判断某个手机号的验证码是否可以重新发送
	 * 
	 * @param key
	 *            : example SysSMSLog.TYPE_WITHDRAW + mobile
	 * @return true 可以发送；false 不可以重新发送
	 */
	public boolean sendVerifyCodeTimeUp(String key) {
		// return true;
		Map<String, Object> cache = getVerifyCodeFromRedis(key);
		if (cache == null) {
			return true;
		}
		Timestamp now = new Timestamp(System.currentTimeMillis());
		Timestamp cacheTime = (Timestamp) cache.get("time");
		long split = (now.getTime() - cacheTime.getTime()) / 1000;
		return split > genCodeTime;
	}
	
	
	/**
	 * 获取白名单列表
	 * @return
	 * @throws Exception
	 *//*
	public List<SysWhiteList> getWhiteList() throws Exception {
		String url = server + "sysWhiteList/list";
		SysWhiteList[] sysWhiteLists = restTemplate.getForObject(url, SysWhiteList[].class);
		return Arrays.asList(sysWhiteLists);
	}

	*//**
	 * 根据地址和类型判断是否在白名单中
	 * @param ipAddress
	 * @param type
	 * @return
	 * @throws Exception 
	 *//*
	public boolean whiteListPass(String ipAddress, String type) throws Exception {
		List<SysWhiteList> list =  getWhiteList();
		for(SysWhiteList sysWhiteList : list) {
			if (ipAddress.equals(sysWhiteList.getIpAddress()) && type.equals(sysWhiteList.getType())) {
				return true;
			}
		}
		return false;
	}*/
}
